#include <QCoreApplication>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <regex>
using namespace std;
struct rule
{
public:
    string NAME;
    int CHOICES;
    int BLANKS;
    string SORTED;
    string UNIQUE;
    long WinRate;
    bool operator()(const rule &i,const rule &j)
    {
        if (i.WinRate < j.WinRate)
            return 1;
        else if (i.WinRate == j.WinRate)
        {if (i.NAME[0]<j.NAME[0])
            return 1;
        }
        else
            return 0;
    }
};

class Lottery
{
public:
    Lottery();
    ~Lottery();
    vector <string> sortByOdds(vector <string> rules);
//private:
    long factorial(int n);
    long C(int n,int m);
    long A(int n,int m);
    long exponential(int n,int m);
    vector<rule> decodeRule(vector <string> rules);
};
Lottery::Lottery()
{

}
Lottery::~Lottery()
{

}

vector<string> Lottery::sortByOdds(vector<string> rules)
{
    vector<string> result;
    vector<rule> rl;
    rule tmp;
    vector<rule>::iterator it;
    rl=decodeRule(rules);
//    for (vector<rule>::iterator itt=rl.begin();itt!=rl.end();itt++)
//        cout<<(*itt).NAME<<'\n';
    sort(rl.begin(),rl.end(),tmp);
//    for (vector<rule>::iterator ittt=rl.begin();ittt!=rl.end();ittt++)
//        cout<<(*ittt).NAME<<'\n';
    for(it=rl.begin();it!=rl.end();it++)
    result.push_back((*it).NAME);
    return result;
}
vector<rule> Lottery::decodeRule(vector<string> rules)
{
    vector<rule> result;
    rule tmp;
    regex regular("^([A-Z][A-Z ]{3,20}): ([1-9]\\d |100 )([1-8]) ([T|F]) ([T|F])$");
    smatch sm;
    for(vector<string>::iterator itVector = rules.begin();itVector!=rules.end();itVector++)
    {
//        cout<<*itVector<<'\n';
        if (regex_match(*itVector,sm,regular))
        {
//        cout<<regex_match(*itVector,sm,regular)<<'\n';
//        cout<<sm.str(0)<<'\n'<<sm.str(1)<<'\n'<<sm.str(2)<<'\n'<<sm.str(3)<<'\n'<<sm.str(4)<<'\n'<<sm.str(5);
        tmp.NAME=sm[1];
        tmp.CHOICES=stoi(sm[2]);
        tmp.BLANKS = stoi(sm[3]);
        tmp.SORTED = sm[4];
        tmp.UNIQUE = sm[5];
        if (tmp.SORTED == "T" && tmp.UNIQUE == "T")
            tmp.WinRate=C(tmp.BLANKS,tmp.CHOICES);
        if (tmp.SORTED == "T" && tmp.UNIQUE == "F")
        {tmp.WinRate=0;
            for(int i=1;i<=tmp.BLANKS;i++)
             tmp.WinRate+=C(i,tmp.CHOICES);
        }
        if (tmp.SORTED == "F" && tmp.UNIQUE == "T")
            tmp.WinRate=A(tmp.BLANKS,tmp.CHOICES);
        if (tmp.SORTED == "F" && tmp.UNIQUE == "F")
            tmp.WinRate=exponential(tmp.BLANKS,tmp.CHOICES);
        }
        else
        {
        result.clear();
        break;
        }
        result.push_back(tmp);
    }
    return result;
}

long Lottery::factorial(int n)
{
    if (n>0&&n<1000)
        return n==1?1:n*factorial(n-1);
    else return -1;
}
long Lottery::C(int n, int m)
{
    if (n>0&&m>0&&m>=n)
        return factorial(m)/factorial(n)/factorial(m-n);
    else return -1;
}
long Lottery::A(int n, int m)
{
    if (n>0&&m>0&&m>=n)
        return factorial(m)/factorial(m-n);
    else return -1;
}
long Lottery::exponential(int n,int m)
{
    if (m>0&&m<1000&&n>0&&m>0&&m>=n)
        return n==1?m:m*exponential(n-1,m);
    else return -1;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Lottery lottery;
    vector<string> test,ans;
//    test.push_back("INDIGO: 93 8 T F");
//    test.push_back("ORANGE: 29 8 F T");
//    test.push_back("VIOLET: 76 6 F F");
//    test.push_back("BLUE: 100 8 T T");
//    test.push_back("RED: 99 8 T T");
//    test.push_back("GREEN: 78 6 F T");
//    test.push_back("YELLOW: 75 6 F F");
//    ans=lottery.sortByOdds(test);
//    for(vector<string>::iterator it = ans.begin();it!=ans.end();it++ )
    cout<<lottery.factorial(20);
//    cout<<*it<<'\n';
    return a.exec();
}
